﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Sofire.Data;
using System.Threading;

namespace OracleExpHelper
{
    public partial class FormImport : Form
    {
        public FormImport()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
            this.DoubleBuffered = true;
            btn_Import.Enabled = false;
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            var r2 = Program.Database.ExecuteScalar("SELECT USER FROM DUAL");
            if(!this.IsSuccess(r2)) return;
            this.Text = "ORACLE Import Helper - " + r2.Value;
        }

        private void lbl_Path_DoubleClick(object sender, EventArgs e)
        {
            lbl_Path.Text = "Please double-click this to select the file...";
            btn_Import.Enabled = false;
            var path = this.CreateOpenFile();
            if(path == null) return;
            lbl_Path.Text = path;
            btn_Import.Enabled = true;
        }

        private string CreateOpenFile()
        {
            using(OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = "EXPD Files|*.expd";
                if(dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) return dialog.FileName;
            }
            return null;
        }

        private void SetText(string text)
        {
            if(richTextBox1.InvokeRequired)
            {
                richTextBox1.Invoke(new Action<string>(SetText), text);
                return;
            }
            richTextBox1.AppendText(text);
            richTextBox1.AppendText(Environment.NewLine);
        }

        private void SetProgressMaxValue(int value)
        {
            if(progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new Action<int>(SetProgressMaxValue), value);
                return;
            }
            progressBar1.Maximum = value;
            progressBar1.Value = 0;
        }

        private void SetProgressValue(int value)
        {
            if(progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new Action<int>(SetProgressValue), value);
                return;
            }
            progressBar1.Value = value;
        }

        private void btn_Import_Click(object sender, EventArgs e)
        {
            if(MessageBox.Show("是否开始导入？", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No) return;
            btn_Import.Visible = false;
            richTextBox1.Clear();
            Thread t = new Thread(new ParameterizedThreadStart(Import));
            t.IsBackground = true;
            t.Start();
        }

        private void Import(object e)
        {
            using(FileStream fileStream = new FileStream(lbl_Path.Text, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                StreamReader reader = new StreamReader(fileStream);
                using(var context = Program.Database.Context)
                {
                    context.OpenTransaction();
                    try
                    {
                        StringBuilder builder = new StringBuilder();
                        while(true)
                        {
                            var line = reader.ReadLine();
                            if(line == null) break;
                            if(line == "<EOF>")
                            {
                                var typeName = reader.ReadLine();
                                var name = reader.ReadLine();
                                if(typeName == "TABLE")
                                {
                                    this.SetText("Import table " + name + ".");
                                    this.ImportTable(context, builder, name);
                                }
                                else
                                {
                                    this.SetText("Import " + typeName + " " + name + ".");
                                    var r = context.ExecuteNonQuery(builder.ToString());
                                    if(!this.IsSuccess(r)) return;
                                    this.SetText("Import " + typeName + " " + name + " successful.");
                                }
                                builder = new StringBuilder();
                            }
                            else
                            {
                                builder.AppendLine(line);
                            }
                        }
                        context.Commit();
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        context.Rollback();
                    }
                    context.Close();
                }
            }
            this.BeginInvoke(new Action(() =>
            {
                MessageBox.Show("导入成功...");
                btn_Import.Visible = true;
            }));
        }

        private void ImportTable(QueryContext context, StringBuilder builder, string name)
        {
            using(DataTable table = new DataTable())
            {
                table.ReadXml(new StringReader(builder.ToString()));
                if(cbox_ClearData.Checked)
                {
                    if(cbox_ClearData.Checked)
                    {
                        var r = context.ExecuteNonQuery("DELETE " + name);
                        if(!this.IsSuccess(r)) return;
                        context.Commit();
                    }
                    this.SetProgressMaxValue(table.Rows.Count);
                    context.BulkCopy(new BulkCopyArguments(name, table)
                    {
                        NotifyAfter = 100,
                        BatchSize = 500,
                        RowsCopied = (rowsCopied) =>
                        {
                            this.SetProgressValue((int)rowsCopied);
                            return false;
                        }
                    });
                    //using(var tr = context.ExecuteTable("SELECT * FROM " + name))
                    //{
                    //    if(!this.IsSuccess(tr)) return;
                    //    var sourceTable = tr.Value;
                    //    for(int i = 0 ; i < table.Rows.Count ; i++)
                    //    {
                    //        sourceTable.Rows.Add(table.Rows[i].ItemArray);
                    //        if(i > 0 && i % numericUpDown1.Value == 0)
                    //        {
                    //            this.SetProgressValue(i);
                    //            if(tr.Update() > 0)
                    //            {
                    //                context.Commit();
                    //            }
                    //            if(!this.IsSuccess(tr)) return;
                    //        }
                    //    }
                    //    if(tr.Update() > 0)
                    //    {
                    //        context.Commit();
                    //    }
                    //    if(!this.IsSuccess(tr)) return;
                    this.SetProgressValue(table.Rows.Count);

                    this.SetText("Import table " + name + " " + table.Rows.Count + " rows successful.");
                }

            }
        }
    }
}
